<template>
  <div class="formCon" :style="{ height: height }">
    <el-form
      ref="formRef"
      :inline="inline"
      :model="form"
      :rules="disabled ? {} : ruleObj"
      :disabled="disabled"
      :class="className"
    >
      <div :class="{ card: columns.length > 1 }" v-for="column in columns">
        <el-form-item
          v-for="col in column.cols"
          :label="col.label"
          :prop="col.prop"
          :key="col.prop"
          :label-width="labelWidth"
          :label-position="col.labelPosition || 'right'"
          :class="{ block: col.type === 'richText', form_item: true }"
          :style="{ width: col.formItemWidth || '30%' }"
          v-show="
            ((col.ifProp && form[col.ifProp] === col.ifValue) || !col.ifProp) &&
            !col.formHide
          "
        >
          <template #label>
            <el-tooltip
              class="box-item"
              effect="light"
              :content="col.tip"
              placement="top"
              v-if="!disabled && col.tip"
            >
              <el-icon class="tip_icon"
                ><WarningFilled :size="30" color="#145FFF"
              /></el-icon>
            </el-tooltip>
            <span class="justify">
              {{ col.label }}
            </span>
          </template>

          <template v-if="col.type === 'slot'">
            <slot :name="col.prop" :key="col.prop" :item="col"></slot>
          </template>
          <!-- 单选框 -->
          <template v-if="col.type === 'radio'">
            <el-radio-group v-model="form[col.prop]" v-if="!disabled">
              <el-radio
                size="default"
                v-for="item in col.options"
                :key="item.value"
                :value="item.value"
                >{{ item.label }}</el-radio
              >
            </el-radio-group>
            <span v-else>{{ form[col.prop] || "-" }}</span>
          </template>
          <!-- 多选框 -->
          <template v-if="col.type === 'checkbox'">
            <el-select
              v-model="form[col.prop]"
              :style="{ width: col.width ? col.width : '240px' }"
              placeholder="请选择"
              v-if="!disabled"
              clearable
              multiple
            >
              <el-option
                v-for="item in col.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
            <span v-else>{{ form[col.prop].join("、") || "-" }}</span>
          </template>
          <!-- 单选框 -->
          <template v-if="col.type === 'select'">
            <el-select
              v-model="form[col.prop]"
              :style="{ width: col.width ? col.width : '240px' }"
              placeholder="请选择"
              v-if="!disabled"
              :disabled="col.disabled || false"
              clearable
              filterable
              @change="selectChangeRule(col)"
            >
              <el-option
                v-for="item in col.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
            <span v-else>{{
              getLabelByValue(col.options, form[col.prop]) ||
              "-"
            }}</span>
          </template>
          <!-- 级联筛选 -->
          <template v-if="col.type === 'cascader'">
            <el-cascader
              :style="{ width: col.width || '240px' }"
              placeholder="请选择"
              v-if="!disabled"
              v-model="form[col.prop]"
              @change="cascaderChange(form[col.prop], col)"
              :options="col.options"
              :props="col.props"
              filterable
            />
            <span v-else>{{ form[col.prop] || "-" }}</span>
          </template>
          <!-- 输入框 -->
          <template v-if="col.type === 'input'">
            <el-input
              v-model="form[col.prop]"
              :style="{ width: col.width || '240px' }"
              :placeholder="col.placeholder || '请输入' + col.label"
              v-if="!disabled"
              :maxlength="col.limit || 50"
              :show-word-limit="col.showLimit"
              autocomplete="off"
              :disabled="col.disabled"
            >
              <template #append v-if="col.append">{{ col.append }}</template>
            </el-input>
            <span v-else>{{ form[col.prop] || "-" }}{{ col.append }}</span>
          </template>
          <!-- 数字输入框 -->
          <template v-if="col.type === 'numberInput'">
            <el-input
              v-model="form[col.prop]"
              :style="{ width: col.width ? col.width : '240px' }"
              :placeholder="col.placeholder || '请输入' + col.label"
              :max="col.max || 'Infinity'"
              v-if="!disabled"
              :precision="col.precision"
              :step="col.step"
              autocomplete="off"
            >
              <template #append v-if="col.append">{{ col.append }}</template>
            </el-input>
            <span v-else>{{ form[col.prop] || "-" }}{{ col.append }}</span>
          </template>
          <!-- 密码输入框 -->
          <template v-if="col.type === 'password'">
            <el-input
              v-model="form[col.prop]"
              type="password"
              style="width: 240px"
              :placeholder="col.placeholder || '请输入' + col.label"
              v-if="!disabled"
              :maxlength="col.limit || 20"
              :show-word-limit="col.showLimit"
              autocomplete="off"
            >
              <template #append v-if="col.append">{{ col.append }}</template>
            </el-input>
            <span v-else>{{ form[col.prop] || "-" }}{{ col.append }}</span>
          </template>
          <!-- 输入框 -->
          <template v-if="col.type === 'textarea'">
            <el-input
              type="textarea"
              :rows="3"
              v-model="form[col.prop]"
              :style="{ width: col.width ? col.width : '240px' }"
              :placeholder="'请输入' + col.label"
              v-if="!disabled"
              :maxlength="col.limit || 50"
              :show-word-limit="col.showLimit"
            ></el-input>
            <span v-else>{{ form[col.prop] || "-" }}</span>
          </template>
          <!-- 时间日期 -->
          <template v-if="col.type === 'datetime'">
            <el-date-picker
              v-model="form[col.prop]"
              :style="{ width: col.width ? col.width : '240px' }"
              type="datetime"
              :placeholder="col.placeholder || '选择日期时间'"
              format="YYYY/MM/DD HH:mm:ss"
              value-format="YYYY/MM/DD HH:mm:ss"
              v-if="!disabled"
            >
            </el-date-picker>
            <span v-else>{{ form[col.prop] || "-" }}</span>
          </template>
          <!-- 日期 -->
          <template v-if="col.type === 'date'">
            <el-date-picker
              v-model="form[col.prop]"
              :style="{ width: col.width ? col.width : '240px' }"
              type="date"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              placeholder="请选择日期"
              :disabled-date="col.disabledDate || null"
              v-if="!disabled"
            />
            <span v-else>{{ form[col.prop] || "-" }}</span>
          </template>
          <!-- 时间日期 -->
          <template v-if="col.type === 'datetimerange'">
            <el-date-picker
              v-model="form[col.prop]"
              style="width: 240px"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              v-if="!disabled"
            >
            </el-date-picker>
            <span v-else
              >{{ form[col.prop] }}-{{
                form[col.endProp]
              }}</span
            >
          </template>
          <!-- 时间区间 -->
          <template v-if="col.type === 'timeRange'">
            <el-time-picker
              v-model="form[col.prop]"
              style="width: 240px"
              is-range
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              format="HH:mm"
              value-format="HH:mm"
              v-if="!disabled"
            />
            <span v-else>{{ form[col.prop] }}-{{ form[col.endProp] }}</span>
          </template>
          <!-- 上传单张图片 -->
          <!-- <template v-if="col.type === 'image'">
            <ImageUpload
              :fileType="fileType"
              :limit="1"
              v-model="form[col.prop]"
              listType="picture-card"
              :isShowTip="false"
              :disabled="disabled"
              :className="col.className || ''"
            ></ImageUpload>
          </template> -->
          <!-- 上传多张图片 -->
          <!-- <template v-if="col.type === 'images'">
            <ImageUpload
              :fileType="fileType"
              :limit="col.limit"
              v-model="form[col.prop]"
              listType="picture-card"
              :isShowTip="false"
              :disabled="disabled"
              :className="col.className || ''"
            ></ImageUpload>
          </template> -->
          <!-- 时间线 -->
          <template v-if="col.type === 'timeline'">
            <el-timeline>
              <el-timeline-item
                v-for="(activity, index) in form[col.prop]"
                :key="index"
                :icon="activity.icon"
                :type="activity.type"
                :color="activity.color"
                :size="activity.size"
                :hollow="activity.hollow"
                :timestamp="activity.timestamp"
              >
                {{ activity.content }}
              </el-timeline-item>
            </el-timeline>
          </template>
          <el-tooltip
            class="box-item"
            effect="light"
            :content="col.endTip"
            placement="top"
            v-if="!disabled && col.endTip"
          >
            <el-icon class="end_tip_icon"
              ><WarningFilled color="#145FFF"
            /></el-icon>
          </el-tooltip>
        </el-form-item>
      </div>
    </el-form>
  </div>
  <div class="dialog-footer" :style="{ 'text-align': footerAlign }">
    <el-button :type="b.type" v-for="b in buttons" @click="buttonFunc(b)">{{
      b.text
    }}</el-button>
  </div>
</template>
<script setup>
// import ImageUpload from "@/components/ImageUpload/index.vue";
const { proxy } = getCurrentInstance();
const emit = defineEmits(["save", "submit", "cancel"]);
const props = defineProps({
  inline: {
    type: Boolean,
    default: true,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  columns: {
    type: Array,
    required: true,
    default: [],
  },
  data: {
    type: Object,
    required: true,
  },
  treeData: {
    type: Array,
    required: false,
    default: [],
  },
  rules: {
    type: Object,
    required: true,
  },
  labelWidth: {
    type: String,
    default: "100px",
  },
  buttons: {
    type: Array,
    default: [{ type: "default", text: "返回", prop: "cancel" }],
  },
  className: {
    type: String,
    default: "",
  },
  height: {
    type: String,
    default: "calc(100vh - 90px)",
  },
  footerAlign: {
    // 底部按钮对齐方式
    type: String,
    default: "left",
  },
  slotArr: {
    type: Array,
    required: false,
    default: [],
  },
});
watch(props.data, () => {
  props.slotArr.forEach((item) => {
    form.value[item] = props.data[item];
  });
});
const form = ref(JSON.parse(JSON.stringify(props.data)));
function getLabelByValue(arr, value){
  let res = ""
  arr.some((item)=>{
    if(item.value === value){
res = item.label
return true;
    }
  })
  return res;
}
function valueHtmlChange(val, prop) {
  form.value[prop] = val.value;
}
const fileType = ref(["png", "jpg", "jpeg"]);

function buttonFunc(b) {
  if (["cancel", "examine"].includes(b.prop)) {
    emit(b.prop, form.value);
  } else {
    proxy.$refs["formRef"].validate((valid) => {
      if (valid) {
        emit(b.prop, form.value);
      }
    });
  }
}
// select change改变rule的必填校验
function ruleObjFunc() {
  let res = {};
  for (let i in props.rules) {
    res[i] = props.rules[i];
  }
  return res;
}
const ruleObj = ref(ruleObjFunc());
function selectChangeRule(col) {
  if (col.ruleProp && col.ruleProp.length > 0) {
    col.ruleProp.forEach((c) => {
      ruleObj.value[c][0].required = col.ruleMap[form.value[col.prop]];
    });
  }
}


// 级联
function cascaderChange(val, col, parentCol, index) {
  col.extra &&
    col.extra.forEach((a, aIndex) => {
      if (val.length > aIndex) {
        if (parentCol) {
          form.value[parentCol.prop][index][a] = val[aIndex];
        } else {
          form.value[a] = val[aIndex];
        }
      }
    });
}
// 地图
onMounted(() => {
  nextTick(() => {
    initMap();
  });
});
const map = ref(null);
const searchKey = ref("");
const suggestions = ref([]);
let marker = null;
const showSelect = ref(false);
const onSearchInput = async (col) => {
  if (searchKey.value) {
    form.value[col.longitudeProp] = "";
    form.value[col.latitudeProp] = "";
    form.value[col.prop] = "";
    const autocomplete = new AMap.Autocomplete({});
    autocomplete.search(searchKey.value, (status, result) => {
      if (status === "complete" && result.tips) {
        showSelect.value = true;
        suggestions.value = result.tips.filter((item) => item.location);
      }
    });
  } else {
    suggestions.value = [];
    form.value[col.prop] = "";
    form.value[col.longitudeProp] = "";
    form.value[col.latitudeProp] = "";
  }
};
function selectSuggestion(e, col) {
  showSelect.value = false;
  suggestions.value = [];
  form.value[col.prop] = e.name;
  form.value[col.longitudeProp] = e.location.lng;
  form.value[col.latitudeProp] = e.location.lat;
  searchKey.value = e.name;
  map.value.setZoomAndCenter(
    16,
    new AMap.LngLat(e.location.lng, e.location.lat)
  );
  if (marker) {
    marker.remove();
  }
  marker = new AMap.Marker({
    position: new AMap.LngLat(e.location.lng, e.location.lat), // 经纬度
    map: map.value, // 指定将标记点添加到哪个地图实例中
  });
  // 将标记点显示在地图上
  marker.setMap(map.value);
}
function hideSuggestions(col) {
  if (showSelect.value) {
    showSelect.value = false;
    if (!form.value[col.longitudeProp]) {
      form.value[col.prop] = "";
      searchKey.value = "";
    }
  }
}
// 地图
function initMap() {
  props.columns.forEach((cols) => {
    cols.cols.forEach((c) => {
      if (c.type === "gis") {
        if (form.value.longitude && form.value.latitude) {
          map.value = new AMap.Map("mapContainer", {
            zoom: 16,
            center: [form.value.longitude, form.value.latitude],
            resizeEnable: true,
          });
          marker = new AMap.Marker({
            position: new AMap.LngLat(
              form.value.longitude,
              form.value.latitude
            ), // 经纬度
            map: map.value, // 指定将标记点添加到哪个地图实例中
          });
          // 将标记点显示在地图上
          marker.setMap(map.value);
          searchKey.value = form.value.address;
        } else {
          map.value = new AMap.Map("mapContainer", {
            zoom: 16,
            resizeEnable: true,
          });
        }
        AMap.plugin(["AMap.PlaceSearch", "AMap.AutoComplete"], function () {});
      }
    });
  });
}
const getSelectRes = (val, col, parentCol, index) => {
  if (parentCol) {
    form.value[parentCol.prop][index][col.prop] = val;
  } else {
    form.value[col.prop] = val;
  }
};
const getTypeSelectRes = (val, col, parentCol, index) => {
  if (parentCol) {// 表单-表格使用
    form.value[parentCol.prop][index] = val[parentCol.prop][index];
  } else {// 表单使用
    form.value[col.prop] = val[col.prop]
    for(let c in val){
      if(val[c]){
        form.value[c] = val[c];
      }
    }    
  }
};

onUnmounted(() => {
  map.value?.destroy();
});
</script>

<style lang="scss" scoped>
.formCon {
  position: relative;
  overflow-y: auto;
  overflow-x: hidden;
  padding-top: 30px;
}
.nowarp {
  :deep(.el-form-item__content) {
    flex-wrap: nowrap;
  }
}

.dialog-footer {
  // position: absolute;
  // bottom: 0;
  text-align: right !important;
  padding: 10px;
  margin: 0 auto;
  // box-shadow: 0 0px 6px rgba(0, 21, 41, 0.08);
}

.el-form {
  padding-bottom: 60px;
}
.block {
  :deep(.el-form-item__content) {
    display: block;
  }
}
.card {
  padding: 20px;
  box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.12);
  margin-bottom: 20px;
  box-sizing: border-box;
}
#mapContainer {
  width: 240px;
  height: 240px;
  background-color: #dde3e8;
}
.top3 {
  position: relative;
  top: 3px;
}
.grid1 {
  display: grid;
  grid-template-columns: 1fr;
  width: 100%;
  position: relative;
  .suggestion {
    position: absolute;
    top: 32px;
    left: 0px;
    width: 100%;
    max-height: 290px;
    overflow-y: auto;
    z-index: 999;
    background: #fff;
    box-sizing: border-box;
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
    list-style: none;
    cursor: pointer;
    .textHide:hover {
      background-color: rgb(235.9, 245.3, 255);
    }
  }
}
.suggestion_mask {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100vh;
  background-color: transparent;
}
.textHide {
  padding: 10px 20px;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-all;
  white-space: nowrap;
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
.size12 {
  font-size: 12px;
  line-height: 12px;
}
.size14 {
  font-size: 14px;
  line-height: 14px;
}
.wth20 {
  width: 20px;
}
.flex {
  display: flex;
}
.dialog_title {
  font-size: 16px;
  color: #333333;
}
.sub_title {
  font-size: 14px;
  color: #9c9c9c;
}
.inline_block {
  display: inline-block;
}
.form_item {
  position: relative;
}
.justify {
  position: relative;
}
.tip_icon {
  font-size: 18px;
  top: 7px;
}
.end_tip_icon {
  font-size: 18px;
}
</style>
